# -*- coding: utf-8 -*-
'''
利用sklearn实现knn
'''

import os
import numpy as np
from sklearn import neighbors 
from sklearn.model_selection import cross_val_score

testFiles = os.listdir(".//data//testDigits")
trainingFiles = os.listdir(".//data//trainingDigits")

def img2vector(filename):
    vect = np.zeros((1,1024))
    fr = open(filename)
    for i in range(32):
        line = fr.readline()
        for j in range(32):
            vect[0,32*i+j] = int(line[j])
    fr.close()
    return vect


def getData(filelist, DigitsName):
    labels = []
    m = len(filelist)
    Mat = np.zeros((m,1024))
    for i in range(m):
        fileName = '.\\data\\'+DigitsName+'\\' + filelist[i]
        labels.append(filelist[i].split('_')[0])
        Mat[i,:] = img2vector(fileName)
    return labels, Mat

trainingLabels, trainingMat = getData(trainingFiles, 'trainingDigits')
testLabels, testMat = getData(testFiles, 'testDigits')

# 取不同的k值，利用5折交叉验证寻找最优k
k_range = range(1,6)
maccs = []
for i in k_range:
    knn = neighbors.KNeighborsClassifier(n_neighbors = i)
    scores = cross_val_score(knn, trainingMat, trainingLabels, cv=5)
    print('When K = %s：' % i)
    print('Accuracies: %s' % scores)
    macc = np.mean(scores)
    print('Mean accuracy: %s' % macc)
    maccs.append(macc)

bestk = maccs.index(max(maccs)) + 1
print("Best K: %s" % bestk)

# 利用最优k建立模型
knn = neighbors.KNeighborsClassifier(n_neighbors = bestk)
knn.fit(trainingMat, trainingLabels) 
# 预测
res = knn.predict(testMat)
print(res) 

score = knn.score(testMat, testLabels)
print('Accuracy:',score) 

res = knn.predict([testMat[0]]) # 这里需要注意，传参为多维数组
print(res)




